// Copyright (c) 2022 Presto Labs Pte. Ltd.
// Author: lucasyoo

#pragma once

#include "coin2/strategy/hamm/hamm.pb.h"
#include "coin2/strategy/order_executor/layering_executor2.h"
#include "presto/quant/math/sampled_moving_average.h"

namespace coin2::strategy::hamm {

using coin2::exchange::base::feed::FeedUpdate;
using coin2::strategy::order_executor::LayeringExecutor2;
using OrderSpec = coin2::exchange::base::order::OrderSpec;
using OrderDuration = coin::proto::OrderDuration;
using OrderSide = coin::proto::OrderSide;
using OrderType = coin::proto::OrderType;

class AggressiveController {
 public:
  AggressiveController(
      const AggressiveControllerConfig& agg_config,
      LayeringExecutor2* layer_exec,
      int64_t order_update_period_sec);

  void UpdateData(
      int64_t ts,
      double volatility,
      std::pair<double, double> bbo,
      std::pair<double, double> fair_bbo);

  void Reset();

  bool IsOrderbookUnbalanced() const;
  bool IsReversionRegime() const;

  std::pair<double, double> GetOrderFromBook(const FeedUpdate& upd);

  void ManageAggOrders(const FeedUpdate& upd);

 private:
  LayeringExecutor2* layer_exec_;
  int64_t cooldown_period_;
  int64_t order_update_period_;
  double sw_quote_thold_;
  double lw_quote_thold_;
  int64_t update_intv_;
  double midp_ret_thold_;
  double vol_thold_;
  double skip_quote_thold_;
  double skip_bid_thold_;
  int max_consecutive_skip_;
  double pricing_diff_thold_;

  int64_t ts_;
  int64_t last_update_ts_{0};
  int64_t last_cooldown_ts_{0};
  int64_t last_agg_ts_{0};
  double best_bid_;

  presto::math::SampledMovingAverage<double> midp_, vol_;
  presto::math::TimeWindowMovingAverage<double> sw_fill_, lw_fill_;
  std::pair<double, double> fair_bbo_, bbo_;
};

}  // namespace coin2::strategy::hamm